from . import passport_blueprint
from flask import request, make_response, jsonify, session
from libs.captcha.captcha import captcha
from info import redis_store, db
from info import constants
from info.response_code import RET
import re
from info.models import User
import random
from info.utils.sms import sendTemplateSMS


@passport_blueprint.route('/image_code')
def image_code():
    '''生成图形验证码'''
    # 1.随机生成4位字符串
    # 2.调用Pillow包中的类，进行图形绘制
    # 3.将图片输出到response对象中

    # 调用第三方的包，生成图形验证码
    text, code, image = captcha.generate_captcha()
    # 1.保存code到redis，用于后续验证
    # 获取客户端请求的唯一标识
    code_id = request.args.get('code_id')
    redis_store.setex(code_id, constants.IMAGE_CODE_REDIS_EXPIRES, code)
    # 返回图片
    response = make_response(image)
    # 设置响应头中，返回数据的类型，告诉浏览器如何解析返回的数据
    response.headers['Content-Type'] = 'image/png'
    return response


@passport_blueprint.route('/sms_code', methods=["POST"])
def sms_code():
    '''短信验证码'''
    # 1接收手机号、图形验证码
    mobile = request.json.get('mobile')
    image_request = request.json.get('image_code')
    image_code_id = request.json.get('image_code_id')
    # print(image_code_id)

    # 2.1从redis中读取图形验证码
    image_redis = redis_store.get(image_code_id)
    if image_redis is None:
        return jsonify(errno=RET.NODATA, errmsg='图形验证码过期')
    # 2验证图形验证码：所有从redis中读取出来的数据，都是bytes类型
    if image_request != image_redis.decode():
        return jsonify(errno=RET.DATAERR, errmsg='图形验证码错误')

    # 3验证手机号格式
    if not re.match(r'^1[3-9]\d{9}$', mobile):
        return jsonify(errno=RET.NODATA, errmsg='手机号格式错误')
    # 4判断手机号是否存在
    mobile_count = User.query.filter_by(mobile=mobile).count()
    if mobile_count > 0:
        return jsonify(errno=RET.DATAEXIST, errmsg='手机号已经被使用')
    # 随机生成一个6位的数字
    smscode = str(random.randint(100000, 999999))
    # 发送短信[验证码字符串，有效时间]
    # sendTemplateSMS(mobile,[smscode,'5'],1)
    print(smscode)
    # 保存验证码到redis
    redis_store.setex(mobile, constants.SMS_CODE_REDIS_EXPIRES, smscode)

    # 响应
    return jsonify(errno=RET.OK, errmsg='')


@passport_blueprint.route('/register', methods=['POST'])
def register():
    '''注册：向用户表中添加数据'''
    # 1.接收：手机号，短信验证码，密码
    mobile = request.json.get('mobile')
    smscode = request.json.get('smscode')
    password = request.json.get('password')

    # 2.验证
    # 2.1验证所有的数据非空
    if not all([mobile, smscode, password]):
        return jsonify(errno=RET.NODATA, errmsg='数据不完整')
    # 2.2读取验证验证码
    smscode_redis = redis_store.get(mobile)
    if smscode_redis is None:
        return jsonify(errno=RET.NODATA, errmsg='短信验证码过期')
    # 2.3验证两个短信验证码是否一致
    if smscode != smscode_redis.decode():
        return jsonify(errno=RET.DATAERR, errmsg='短信验证码错误')

    # 3.处理：新建用户对象，并保存
    user = User()
    user.mobile = mobile
    user.nick_name = mobile
    # user.password_hash=加密函数(password)
    #user.set_password(password)
    user.password = password
    db.session.add(user)
    db.session.commit()

    # 4.响应
    return jsonify(errno=RET.OK, errmsg='')


@passport_blueprint.route('/login', methods=['POST'])
def login():
    '''登录：查询用户'''
    # 1.接收
    mobile = request.json.get('mobile')
    password = request.json.get('password')

    # 2.验证：直接进行查询，如果未查到，说明参数错误
    if not all([mobile, password]):
        return jsonify(errno=RET.NODATA, errmsg='参数不完整')

    # 3.处理
    # 3.1查询用户
    user = User.query.filter_by(mobile=mobile).first()
    if user is None:
        return jsonify(errno=RET.DATAERR, errmsg='手机号错误')
    # 3.2验证密码：将密码加密，对两个加密的密码进行验证
    if user.check_password(password):
        # 密码正确
        # 登录成功后，需要进行状态保持，在其它的视图中，可以用于进行是否登录的判断
        session['user_id'] = user.id
        session['nick_name'] = user.nick_name
        return jsonify(errno=RET.OK, errmsg='')
    else:
        # 密码错误
        return jsonify(errno=RET.DATAERR, errmsg='密码错误')
        # 4.响应


@passport_blueprint.route('/logout', methods=['POST'])
def logout():
    '''退出：删除状态保持的信息'''
    # 从字典中删除指定的键
    session.pop('user_id')
    session.pop('nick_name')
    return jsonify(errno=RET.OK, errmsg='')
